package com.fingard.dsp.bank.directbank.vbao01;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.vbao.service.trade.VbaoChargeSystemHandler;
import com.vbao.service.trade.bean.request.BatchDKRequest;
import com.vbao.service.trade.bean.request.BatchDKRequestOrderInfos;
import com.vbao.service.trade.bean.request.BatchQueryDetailRequest;
import com.vbao.service.trade.bean.request.TradeRequestXml;
import com.vbao.service.trade.utils.TradeCodeEnum;

import java.net.URLDecoder;
import java.util.List;

public class VBAO01BatPayRec extends VBAO01Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqBat.ownAct + "]商户配置信息";
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;

                retAts.writeRetToATS();
                return retAts;
            }

            BatchDKRequest batchDKRequest = new BatchDKRequest();

            // 批量代收付汇总信息
            batchDKRequest.setVersion("6.0");
            batchDKRequest.setInputCharset(getCharset());
            batchDKRequest.setSignType("MD5");
            batchDKRequest.setCustomerNo(actItem.merchantId);
            
            String goodNo = "";
    		boolean useEachGoodNo = getBankConfig().getValueAsBool("isUseEachGoodNo");
    		if (useEachGoodNo) {
    			goodNo = actItem.goodNo;
    		} else {
    			goodNo = getBankConfig().getValueAsString("GoodNo");
    		}
    		if (StringHelper.isNullOrEmpty(goodNo)) {
    			WriteBankLogLn("配置文件缺失'GoodNo'配置!");
    		}
    		
            batchDKRequest.setGoodNo(goodNo);
            batchDKRequest.setBatchOrderNo(p_reqBat.reqBatchNO);
            batchDKRequest.setTotalNum(p_reqBat.totalNum);
            batchDKRequest.setTotalPrice(p_reqBat.totalAmt);
            batchDKRequest.setActName("");
            batchDKRequest.setActId("");
            batchDKRequest.setActLineCode("");
            batchDKRequest.setNotifyUrl("");
            batchDKRequest.setSingleNoticeURL("");
            batchDKRequest.setBranch1("");
            batchDKRequest.setBranch2("");
            batchDKRequest.setBranch3("");
            batchDKRequest.setSalesChannel("");
            batchDKRequest.setCustProductCode("");

            List<BatchDKRequestOrderInfos> SingleOrderList = batchDKRequest.getOrderInfos();
            while (p_reqBat.readRecord()) {
                BatchDKRequestOrderInfos singleRequest = new BatchDKRequestOrderInfos();

                // 批量代收付单笔明细信息
                singleRequest.setOrderNo(p_reqBat.readedDetail.askNumber);
                singleRequest.setOrderAmount(p_reqBat.readedDetail.payAmount);

                String accType = "0";
                if (!"1".equals(p_reqBat.readedDetail.isPrivate)) {
                    accType = "1";
                }
                singleRequest.setAccType(accType);

                String cardType = "0"; /* 银行卡 : 默认值 */
                if ("1".equals(p_reqBat.readedDetail.cardType)) {
                    cardType = "1"; /* 存折 */
                }
                if ("3".equals(p_reqBat.readedDetail.cardType) || "4".equals(p_reqBat.readedDetail.cardType)) {
                    cardType = "2"; /* 信用卡 */
                }
                singleRequest.setBankCardType(cardType);

                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    singleRequest.setBankCode(getBankConfig().getMapValueByKey("BankCodeMapping", p_reqBat.readedDetail.recBankCode));
                    singleRequest.setBankCardNo(p_reqBat.readedDetail.recAct);
                    singleRequest.setBankCardName(p_reqBat.readedDetail.recName);
                } else {
                    singleRequest.setBankCode(getBankConfig().getMapValueByKey("BankCodeMapping", p_reqBat.readedDetail.payBankCode));
                    singleRequest.setBankCardNo(p_reqBat.readedDetail.payAct);
                    singleRequest.setBankCardName(p_reqBat.readedDetail.payName);
                }

                String certType = "";
                String certId = "";
                String mobile = "";
                String expireDate = "";
                String cvv2 = "";

                // 当为信用卡时，以下节点ATS必须传值
                if (p_reqBat.readedDetail.cvv2.length() > 0 && p_reqBat.readedDetail.expiredDate.length() > 0) {
                    mobile = p_reqBat.readedDetail.cellPhone;
                    expireDate = p_reqBat.readedDetail.expiredDate;
                    cvv2 = p_reqBat.readedDetail.cvv2;
                }
                certType = convertCertTypeToBank(p_reqBat.readedDetail.certType);
                certId = p_reqBat.readedDetail.certNum;

                singleRequest.setCertType(certType);
                singleRequest.setCertId(certId);
                singleRequest.setMobile(mobile);
                singleRequest.setCreditValid(expireDate); /* ATS必须按  "YYMM" 格式传值 */
                singleRequest.setCreditCvv2(cvv2);

                singleRequest.setBankProvince("");
                singleRequest.setBankCity("");
                singleRequest.setBankLineCode(p_reqBat.readedDetail.cnapsCode);
                singleRequest.setBankName(p_reqBat.readedDetail.cnapsName);

                String productName = p_reqBat.readedDetail.memo;
                if (StringHelper.isNullOrEmpty(productName)) {
                    productName = p_reqBat.readedDetail.useType;
                }
                if (StringHelper.isNullOrEmpty(productName)) {
                    productName = p_reqBat.readedDetail.abstractATS;
                }
                singleRequest.setProductName(productName); /* 保单号|摘要 */
                singleRequest.setProtocolNo(p_reqBat.readedDetail.authCode);

                SingleOrderList.add(singleRequest);
            }

            VbaoChargeSystemHandler vbaoChargeHandler = new VbaoChargeSystemHandler();
            TradeRequestXml tradeRequestXml = vbaoChargeHandler.creatRequestXml(batchDKRequest, actItem.saltKey, getCharset(), TradeCodeEnum.BATCH_DK.getCode());

            WriteBankLogLn2("批量代收付发送微保请求报文明文:\r\n" + tradeRequestXml.getOriRequestXml());
            WriteBankLogStep2(tradeRequestXml.getRequestXml());

            if (tradeRequestXml.getErrMsg() == null) {
                String submitURL = bankFront.getUrl("batRecPaySubmit");
                boolean isEachBatUrl = getBankConfig().getValueAsBool("useEachBatUrl");
                if (isEachBatUrl) {
                	if ("1988".equals(p_reqBat.reqHeader.transType)) {
                		submitURL = bankFront.getUrl("batPaySubmit");
                	} else {
                		submitURL = bankFront.getUrl("batRecSubmit");
                	}
                }
                WriteBankLogLn2("微保批量代收付交易服务地址: " + submitURL);

                // 发送微保并获取返回
                String returnDKPayxml = vbaoChargeHandler.http(submitURL, tradeRequestXml.getRequestXml(), getCharset());
                WriteBankLogStep3(returnDKPayxml);

                if (StringHelper.hasAnyChar(returnDKPayxml)) {
                    String returnOriDKPayxml = Base64vbao.decode(returnDKPayxml, getCharset());
                    //returnOriDKPayxml = new String(returnOriDKPayxml.getBytes(), getCharset());
                    returnOriDKPayxml = URLDecoder.decode(returnOriDKPayxml, getCharset());
                    WriteBankLogLn2("微保批量代收付返回报文明文:\r\n" + returnOriDKPayxml);

                    // 解析微保返回
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnOriDKPayxml, tmpSbMsg);
                    if (tmpBkReader != null) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpBkReader.getFirstText("/TResponse/ResultInfo/Description");

                        String tmpResultCode = tmpBkReader.getFirstText("/TResponse/ResultInfo/ResultCode");
                        String tmpErrCode = tmpBkReader.getFirstText("/TResponse/ResultInfo/ErrCode");

                        retAts.transState = StringHelper.joinNotEmpty("+", tmpResultCode, tmpErrCode);
                        retAts.payInfoCode = tmpErrCode;

                        String reqSeqID = tmpBkReader.getFirstText("/TResponse/OrderInfo/BatchOrderNo");
                        if (StringHelper.hasAnyChar(reqSeqID)) {
                            retAts.reqSeqID = reqSeqID;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "微保响应内容为空";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tradeRequestXml.getErrMsg();
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();

            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    /**
     * 批量收付状态查询
     */
    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryBat.ownAct, "");
            if (actItem == null) {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryBat.ownAct + "]商户配置信息";
                retAts.writeAfterDetail();
                return retAts;
            }

            BatchQueryDetailRequest batchQueryRequest = new BatchQueryDetailRequest();

            // 批量代收付查询请求数据
            batchQueryRequest.setVersion("6.0");
            batchQueryRequest.setInputCharset(getCharset());
            batchQueryRequest.setSignType("MD5");
            batchQueryRequest.setCustomerNo(actItem.merchantId);
            batchQueryRequest.setBatchOrderNo(p_reqQryBat.reqBatchNO);
            batchQueryRequest.setBatchSeqNo("");
            batchQueryRequest.setSign("");

            VbaoChargeSystemHandler vbaoChargeHandler = new VbaoChargeSystemHandler();
            TradeRequestXml tradeRequestXml = vbaoChargeHandler.creatRequestXml(batchQueryRequest, actItem.saltKey, getCharset(), TradeCodeEnum.BATCH_QUERY_DETAIL.getCode());

            WriteBankLogLn2("微保批量代收付状态查询请求报文明文:\r\n" + tradeRequestXml.getOriRequestXml());
            WriteBankLogStep2(tradeRequestXml.getRequestXml());

            if (tradeRequestXml.getErrMsg() == null) {
                String submitURL = bankFront.getUrl("batRecPayQuery");
                boolean isEachBatUrl = getBankConfig().getValueAsBool("useEachBatUrl");
                if (isEachBatUrl) {
                	if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                		submitURL = bankFront.getUrl("batPayQuery");
                	} else {
                		submitURL = bankFront.getUrl("batRecQuery");
                	}
                }
                String charsetQry = getCharset();
                WriteBankLogLn("charset:"+charsetQry);
                WriteBankLogLn2("微保批量代收付状态查询服务地址: " + submitURL);

                // 发送微保并获取返回
                String returnDKPayxml = vbaoChargeHandler.http(submitURL, tradeRequestXml.getRequestXml(), charsetQry);
                WriteBankLogStep3(returnDKPayxml);

                if (StringHelper.hasAnyChar(returnDKPayxml)) {
                    String returnOriDKRecxml = Base64vbao.decode(returnDKPayxml, charsetQry);
                    returnOriDKRecxml = URLDecoder.decode(returnOriDKRecxml, charsetQry);
                    WriteBankLogLn2("微保批量代收付状态查询返回报文明文:\r\n" + returnOriDKRecxml);

                    // 解析微保返回
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(returnOriDKRecxml, tmpSbMsg);
                    if (tmpBkReader != null) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpBkReader.getFirstText("/TResponse/ResultInfo/Description");

                        String tmpResultCode = tmpBkReader.getFirstText("/TResponse/ResultInfo/ResultCode");
                        if ("T".equals(tmpResultCode)) {
                            String batStatus = tmpBkReader.getFirstText("/TResponse/OrderInfo/PayStatus");
                            if ("1".equals(batStatus)) {
                                String orderInfos = tmpBkReader.getFirstText("/TResponse/OrderInfo/OrderInfos");

                                String[] detailInfos = null;
                                if (orderInfos.contains("|")) {
                                    detailInfos = orderInfos.split("\\|");
                                } else {
                                    detailInfos = new String[]{orderInfos};
                                }

                                for (String detailInfo : detailInfos) {
                                    String[] singleOrderInfo = detailInfo.split("\\^");

                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

                                    if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                                        tmpRetDetail.recAct = singleOrderInfo[5];
                                        tmpRetDetail.recName = singleOrderInfo[6];
                                    } else {
                                        tmpRetDetail.payAct = singleOrderInfo[5];
                                        tmpRetDetail.payName = singleOrderInfo[6];
                                    }

                                    tmpRetDetail.postScript = singleOrderInfo[0];
                                    tmpRetDetail.payAmount = singleOrderInfo[1];

                                    String tmpRespCode = "";
                                    if (singleOrderInfo.length > 13) {
                                        tmpRespCode = singleOrderInfo[13];
                                    }
                                    tmpRetDetail.result = StringHelper.joinNotEmpty("+", singleOrderInfo[2], tmpRespCode);
                                    tmpRetDetail.payInfoCode = tmpRespCode;

                                    String memo = "";
                                    if (singleOrderInfo.length > 14) {
                                        memo = singleOrderInfo[14].trim();
                                    }
                                    if ("".equals(memo)&&"A9999".equals(tmpRespCode)) {
                                        memo = "其他错误";
                                    }
                                    tmpRetDetail.memo = memo;

                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                retAts.transState = StringHelper.joinNotEmpty("+", tmpResultCode, batStatus);
                                retAts.payInfoCode = retAts.transState;
                            }
                        } else {
                        	String bkErrCode = tmpBkReader.getFirstText("/TResponse/ResultInfo/ErrCode");
                            retAts.transState = StringHelper.join("+", tmpResultCode, bkErrCode);
                            retAts.payInfoCode = bkErrCode;
                            if("A2001".equals(bkErrCode)){
                            	if(canBeNotExist(p_reqQryBat, retAts, 35)){
                            		retAts.transState = retAts.transState + "+" + tmpBkReader.getFirstText("/TResponse/ResultInfo/Description");
                            	}
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "微保响应内容为空";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tradeRequestXml.getErrMsg();
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
